package com.meta.nd.vo;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Nd {
	String ndCode;
	String ndName;
	String ndAlias;
	String ndDescription;
	String metaClassName;
	String nvClassName;
	String serviceClassName;
	String dbMapCode;
	String category;
	int minCount;
	int maxCount;
	boolean cursive=false;
	private Date updateTime;
	private List<Nd> children = new ArrayList<Nd>();
	private List<Fd> fds = new ArrayList<Fd>();
	private List<Rd> rds = new ArrayList<Rd>();

	@JsonIgnore
	Nd parent = null;

	public Nd(){

	}
	
	public Date getUpdateTime() {
		return updateTime;
	}
	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}

	@JsonIgnore
	public Nd getParent() {
		return parent;
	}
	public void setParent(Nd parent) {
		this.parent = parent;
	}
	public String getDbMapCode() {
		return dbMapCode;
	}
	public void setDbMapCode(String dbMapCode) {
		this.dbMapCode = dbMapCode;
	}
	
	public String getNdCode() {
		return ndCode;
	}
	public void setNdCode(String ndCode) {
		this.ndCode = ndCode;
	}
	public String getNdName() {
		return ndName;
	}
	public void setNdName(String ndName) {
		this.ndName = ndName;
	}
	public String getNdDescription() {
		return ndDescription;
	}
	public void setNdDescription(String ndDescription) {
		this.ndDescription = ndDescription;
	}
	public List<Nd> getChildren() {
		return children;
	}
	public void setChildren(List<Nd> children) {
		this.children = children;
	}
	public List<Fd> getFds() {
		return fds;
	}
	public void setFds(List<Fd> fds) {
		this.fds = fds;
	}
	
	public int getMinCount() {
		return minCount;
	}
	public void setMinCount(int minCount) {
		this.minCount = minCount;
	}
	public int getMaxCount() {
		return maxCount;
	}
	public void setMaxCount(int maxCount) {
		this.maxCount = maxCount;
	}
	
	
	
	public Nd getDescendant(String code ) {
		
		if (this.getNdCode().equals(code) )
			return this;
		
		for( Nd nd : this.children ) {
			Nd tmp = nd.getDescendant(code);
			if (tmp != null)
				return tmp;
		}		
		
		return null;	
	}
	
	
	
	public Nd getDescendantByName(String name ) {
		
		if (this.getNdName().equals(name) )
			return this;
		
		for( Nd nd : this.children ) {
			Nd tmp = nd.getDescendantByName(name);
			if (tmp != null)
				return tmp;
		}		
		
		return null;	
	}
	
	
	
	
	public Fd getFdByCode( String code) {
		for ( Fd fd : this.fds ) {
			if (fd.getFdCode().equals(code) )
				return fd;
		}
		return null;
	}
	
	
	
	public Fd getFdByName( String fieldName) {
		for ( Fd fd : this.fds ) {
			if (fd.getFdName().equals(fieldName) )
				return fd;
		}
	
		throw new RuntimeException("找不到相应的字段名：" + this.ndName + "." + fieldName);
	}
	
	public Fd existAndGetFdByName( String fieldName ) {
		for ( Fd fd : this.fds ) {
			if (fd.getFdName().equals(fieldName) )
				return fd;
		}
		return null;
	}
	
	public boolean existByName( String fieldName )
	 {
		for ( Fd fd : this.fds ) {
			if (fd.getFdName().equals(fieldName) )
				return true;
		}
		return false;
	}

	@JsonIgnore
	public boolean isRoot() {
		if ( parent == null )
			return true;
		else
			return false;
	}

	@JsonIgnore
	public Nd getRoot() {
		if ( this.isRoot() )
			return this;
		else
			return this.getParent().getRoot();
			
	}
	
	public void addChild( Nd child) {
		this.children.add(child);
		child.setParent(this);
	}
	
	@JsonIgnore
	public Nd getFirstChild() {
		return this.children.get(0);
	}
	
	@JsonIgnore
	public Nd getChildNd( String name ) {
		for ( Nd child : this.getChildren() ) {
			if ( child.ndName.equals(name)) {
				return child;
			}
		}
		return null;
	}


	public Nd getChildByNdCode(String childNdCode){
		for ( Nd child : this.getChildren() ) {
			if ( child.ndCode.equals(childNdCode)) {
				return child;
			}
		}
		return null;
	}

	public Nd findNdByNdCode( String ndCode ){
		if ( this.ndCode.equals(ndCode)) return  this;
		for( Nd child : this.children){
			Nd nd = child.findNdByNdCode(ndCode);
			if ( nd != null ) return nd;
		}
		return null;
	}

	public Nd findNdByNdName( String ndName ){
		if ( this.ndName.equals(ndName)) return  this;
		for( Nd child : this.children){
			Nd nd = child.findNdByNdName(ndName);
			if ( nd != null ) return nd;
		}
		return null;
	}



	public boolean isCursive() {
		return cursive;
	}
	public void setCursive(boolean cursive) {
		this.cursive = cursive;
	}
	
	@JsonIgnore
	public Nd getSingleChildNd () {
		
		return this.children.get(0);
		
	}
	@JsonIgnore
	public List<String> getFieldNames () {
		
		List<String> fieldNames = new ArrayList<String>();
		for ( Fd fd : this.fds ) {
			fieldNames.add(fd.getFdName());
			
		}
		
		return fieldNames;
	}
	public List<Rd> getRds() {
		return rds;
	}
	
	public void setRds(List<Rd> rds) {
		this.rds = rds;
	}
	

	public List<Rd> getRds( String businessType,String orderType ){
		
		List<Rd> subRds = new ArrayList<Rd>();
		
		for ( Rd rd : this.rds ) {
			if ( rd.getTransactionType().equals(businessType) && rd.getOrderType().equals(orderType))
				subRds.add(rd);
		}
		
		return subRds;
	}
	@JsonIgnore
	public List<String> getAllNdCodes(){
		
		List<String> codes = new ArrayList<String>();
		getAllNdCodes(codes);
		return codes;
		
	}
	
	private  void getAllNdCodes (List<String> codes ) {
		
		codes.add(this.getNdCode());
		for (Nd child : this.getChildren())
			child.getAllNdCodes(codes);
				
	}

	public String getNdAlias() {
		return ndAlias;
	}

	public void setNdAlias(String ndAlias) {
		this.ndAlias = ndAlias;
	}

	public String getMetaClassName() {
		return metaClassName;
	}

	public void setMetaClassName(String metaClassName) {
		this.metaClassName = metaClassName;
	}

	public String getNvClassName() {
		return nvClassName;
	}

	public void setNvClassName(String nvClassName) {
		this.nvClassName = nvClassName;
	}

	public String getCategory() {
		return category;
	}

	public void setCategory(String category) {
		this.category = category;
	}

	public String getServiceClassName() {
		return serviceClassName;
	}

	public void setServiceClassName(String serviceClassName) {
		this.serviceClassName = serviceClassName;
	}

	@JsonIgnore
	public String getFinalName(){
		if (!StringUtils.isEmpty(this.ndAlias))
			return ndAlias;

		return this.ndName;
	}
	public void addFd(Fd fd) {
		this.fds.add(fd);
	}
}
